<template>
  <!--模板-->
  定义子类：<br>
  <el-button @click="change1" >直接修改</el-button>
  <el-button @click="change2" >通过方法修改</el-button>
  <el-button @click="reset" >重置</el-button>
  <el-button @click="setValue" >赋值</el-button>

  <hr>
  reactive 的方式：{{nfState}}<br>
  ref 的方式：{{person}}<br><br>
  <hr>

  computed（reactive ）：{{nfState.getName}}<br> 
  computed（ref）：{{person.testComputed}}<br> 
  ref：{{person.name}}<br> 

</template>

<script lang="ts">
  import { defineComponent, reactive, computed, toRaw, ref } from 'vue'
  import type { ComputedRef, Ref } from 'vue'

  import {
    BaseObject
  } from  '../../../lib/main'

  class Person extends BaseObject {
    name: Ref<string>
    age: Ref<number>
    testComputed: ComputedRef

    constructor() {
      super({})
      // 设置属性，直接使用 ref
      this.name = ref('ref')
      this.age = ref(20)
      // 直接使用 computed
      this.testComputed = computed(() => {
        return this.name.value + '测试 computed'
      })

      // 如果需要使用 reset 的话
      this.$value = {
        name: 'ref',
        age: 20
      }
    }
 
    // 设置方法
    add() {
      this.age.value += 1
    }
  }

  class Person2 extends BaseObject {
    #__getters: {[key: string]: ComputedRef}
    name: string
    age: number

    constructor() {
      super({})
      this.#__getters = {}
      // 设置属性
      this.name = '子类的名字'
      this.age = 18

      // 如果需要使用 reset 的话
      this.$value = {
        name: '子类的名字',
        age: 18
      }
    }

    // 设置 computed
    get getName() {
      const re = toRaw(this).#__getters['getName']
      if (re){
        return re
      } else {
        return toRaw(this).#__getters['getName'] = computed(() => {
          return this.name + '--测试 computed'
        })
      }
    }
    // 设置方法
    add() {
      this.age += 1
    }
  }

  /**
   * 演示一种比较“扯淡”的使用方式
   */
  export default defineComponent({
    name: 'state-class-son-demo',
    props: {
    },
    setup(props, context) {
    
      const person = new Person()
      console.log('person--ref 形式：', person)

      const person2 = new Person2()
      const nfState  = reactive(person2)

      console.log('person -- reactive 形式：', person2)
      console.log('nfState：', nfState)
      console.log('nfState--keys：', Object.keys(nfState))
      for(const key in nfState){
        console.log(key)
      }
      console.log('person--keys：', Object.keys(person))
      for(const key in person){
        console.log(key)
      }
      
      const change1 = () => {
        person.name.value = '直接改--' + new Date().valueOf().toString()
        nfState.name = new Date().valueOf().toString()
      }
      const change2 = () => {
        nfState.add()
        person.add()
      }
      const reset = () => {
        nfState.$reset()
        person.$reset()
      }
      
      const setValue = () => {
        nfState.$state = {
          name: 'name 修改：' + new Date().valueOf().toString()
        }
         
      }
       

      return {
        nfState,
        person,
        // 基础
        change1,
        change2,
        reset,
        setValue
      }
    }
  })
</script>